#include <iostream>
#include <assert.h>
#include <stdexcept>
#include <cstring>
#include <cstdlib>
#include "dbcconfig.h"

using namespace std;

ostream & operator <<(ostream & out, Value & val)
{
	ValueType type = val.GetType();

	JSON_ASSERT_MESSAGE(type == StringValue || type == IntValue || type == UIntValue,
			"required StringValue or IntValue or UIntValue");

	switch(type)
	{
		case NullValue:
			break;
		case IntValue:
			out<<val.AsInt()<<flush;
			break;
		case UIntValue:
			out<<val.AsUInt()<<flush;
			break;
		case StringValue:
			out<<val.AsString()<<flush;
			break;
	}

	return out;
}

Value::~Value()
{
	//cout<<"析构value"<<endl;
	Release();
	value_.uint_ = 0;
}

Value::Value(ValueType type)
{
	//cout<<"构造value-ValueType"<<endl;
	SetValueType(type);
}

Value::Value(const char * value)
{
	//cout<<"构造value-const char *"<<endl;
	type_ = StringValue;

	SetStringValue(value);
}

Value::Value(string & value)
{
	//cout<<"构造value-string"<<endl;
	type_ = StringValue;

	SetStringValue(value);
}

Value::Value(int value)
{
	type_ = IntValue;
	value_.int_ = value;
}

Value::Value(unsigned value)
{
	//cout<<"构造value-unsigned"<<endl;
	type_ = UIntValue;
	value_.uint_ = value;
}

Value::Value(const Value & other): type_(other.type_)
{
	//cout<<"构造value-copy"<<endl;
	Copy(other);
}

Value & Value::operator=(const Value & other)
{
	//cout<<"构造value-operator="<<endl;
	//自身赋值
	if (this == &other)
	{
		return *this;
	}

	//释放自身空间
	Release();

	//拷贝旧值
	type_ = other.type_;

	Copy(other);
}

void Value::Copy(const Value & other)
{
	switch (type_)
	{
		case NullValue:
		case IntValue:
		case UIntValue:
			value_ = other.value_;
			break;
		case StringValue:
			{
				int len = strlen(other.value_.string_) + 1;
				value_.string_ = new char[len];

				memset(value_.string_, 0, len);

				strncpy(value_.string_, other.value_.string_, len);
			}
			break;
		case ArrayValue:
		case ObjectValue:
			value_.map_ = new ObjectValues(*other.value_.map_);
			break;
		default:
			break;
	}
}

void Value::Release()
{
	  switch (type_)
	  {
		  case NullValue:
		  case IntValue:
		  case UIntValue:
			break;
		  case StringValue:
			 delete []value_.string_;
			break;
		  case ArrayValue:
		  case ObjectValue:
			delete value_.map_;
			break;
	  default:
		  break;
	  }
}

void Value::SetValueType(ValueType type)
{
	type_ = type;
	static char const emptyString[] = "";

	switch(type)
	{
		case NullValue:
			break;
		case IntValue:
		case UIntValue:
			value_.int_ = 0;
			break;
		case StringValue:
			value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString));
			break;
		case ArrayValue:
		case ObjectValue:
			value_.map_ = new ObjectValues();
			break;
		default:
			break;
	}
}

Value const & Value::nullSingleton()
{

	static Value const nullStatic;
	return nullStatic;
}

Value & Value::operator [] (const char * key)
{
	if ( NullValue != type_ && ObjectValue != type_)
	{
		throw runtime_error("required objectvalue");
	}

	if (NullValue == type_)
	{
		*this = Value(ObjectValue);
	}

	ObjectValues::iterator it = value_.map_->lower_bound(key);

	//key已存在
	if (it != value_.map_->end() && (*it).first == key)
	    return (*it).second;

	//key不存在，则it是能插入的地址
	ObjectValues::value_type defaultValue(key, nullSingleton());

	it = value_.map_->insert(it, defaultValue);

	Value& value = (*it).second;

	return value;
}

bool Value::IsKeyExist(const char * key)
{
	JSON_ASSERT_MESSAGE(type_ == ObjectValue,
			"required ObjectValue");

	if (value_.map_->count(key))
	{
		return true;
	}

	return false;
}

Value & Value::operator [](const string & key)
{
	JSON_ASSERT_MESSAGE(type_ == NullValue || type_ == ObjectValue,
			"required ObjectValue or NullValue");

	if (NullValue == type_)
	{
		*this = Value(ObjectValue);
	}

	ObjectValues::iterator it = value_.map_->lower_bound(key);

	//key已存在
	if (it != value_.map_->end() && (*it).first == key)
	    return (*it).second;

	//key不存在，则it是能插入的地址
	ObjectValues::value_type defaultValue(key, nullSingleton());

	it = value_.map_->insert(it, defaultValue);

	Value& value = (*it).second;

	return value;
}

Value & Value::operator [] (int index)
{
	JSON_ASSERT_MESSAGE(type_ == NullValue || type_ == ArrayValue, "required ArrayValue or NullValue");

	if (NullValue == type_)
	{
		*this = Value(ArrayValue);
	}

	char key[10] = {0};
	sprintf(key, "%d", index);

	ObjectValues::iterator it = value_.map_->lower_bound(key);

	//key已存在
	if (it != value_.map_->end() && (*it).first == key)
	    return (*it).second;

	//key不存在，则it是能插入的地址
	ObjectValues::value_type defaultValue(key, nullSingleton());

	it = value_.map_->insert(it, defaultValue);

	Value& value = (*it).second;

	return value;
}

void Value::SetStringValue(const char * value)
{
	JSON_ASSERT_MESSAGE(type_ == StringValue,
			"in SetStringValue() required StringValue");

	int len = strlen(value) + 1;
	value_.string_ = new char[len];

	memset(value_.string_, 0, len);

	strncpy(value_.string_, value, len);
}

void Value::SetStringValue(const string & value)
{
	JSON_ASSERT_MESSAGE(type_ == StringValue,
			"in SetStringValue() required StringValue");

	int len = value.size() + 1;
	value_.string_ = new char[len];

	memset(value_.string_, 0, len);

	strncpy(value_.string_, value.c_str(), len);
}

void Value::SetIntValue(int value)
{
	JSON_ASSERT_MESSAGE(type_ == IntValue,
			"in SetIntValue() required IntValue");

	value_.int_ = value;
}

void Value::SetUIntValue(unsigned value)
{
	JSON_ASSERT_MESSAGE(type_ == UIntValue,
			"in SetUIntValue() required UIntValue");

	value_.uint_ = value;
}

string Value::AsString()
{
	JSON_ASSERT_MESSAGE(type_ == StringValue,
			"in AsString() required StringValue");

	return value_.string_;
}

int Value::AsInt()
{
	JSON_ASSERT_MESSAGE(type_ == UIntValue || type_ == IntValue ,
			"in AsInt() required UIntValue or IntValue");

	return value_.int_;
}

unsigned Value::AsUInt()
{
	JSON_ASSERT_MESSAGE(type_ == UIntValue || type_ == IntValue,
			"in AsUInt() required UIntValue or IntValue");

	return value_.int_;
}

int Value::Size()
{
	JSON_ASSERT_MESSAGE(type_ == ArrayValue,
			"in Size() required ArrayValue");

	return value_.map_->size();
}

void Value::Print()
{
	switch(type_)
	{
		case NullValue:
			break;
		case IntValue:
		case UIntValue:
			cout<<value_.int_<<flush;
			break;
		case StringValue:
			cout<<value_.string_<<flush;
			break;
		case ArrayValue:
			cout<<"("<<flush;

			for(ObjectIterator it = value_.map_->begin(); it != value_.map_->end(); ++it)
			{

				if (it != value_.map_->begin())
				{
					cout<<","<<flush;
				}

				it->second.Print();
			}

			cout<<")"<<flush;
			break;
		case ObjectValue:
			for(ObjectIterator it = value_.map_->begin(); it != value_.map_->end(); ++it)
			{
				//根据子节点的类型决定输出哪种符号
				switch (it->second.GetType())
				{
					case NullValue:
					case IntValue:
					case UIntValue:
					case StringValue:
					case ArrayValue:
						cout<<"\t"<<flush;
						cout<<it->first<<"="<<flush;
						it->second.Print();
						cout<<endl;
						break;
					case ObjectValue:
						cout<<"<"<<it->first<<">"<<endl;
						it->second.Print();
						cout<<"</"<<it->first<<">"<<endl;
						break;
					default:
						break;
				}
			}
			break;
		default:
			break;
	}
}

int ConfReader::Read(const char * filename, Value & val)
{
	input.open(filename, ios::in);
	char szmsg[100] = {0};

	if (!input.is_open())
	{
		sprintf(szmsg, "unexpeceted data in line=%d", currentline);
		errmsg = szmsg;

		return open_file_error;
	}

	string cont;

	try
	{
		while(!input.eof())
		{
			++currentline;

			getline(input, cont);

			if (cont.empty())
			{
				continue;
			}

			if ('<' == cont[0])
			{
				//new object
				int endpos = cont.find('>');
				string key = cont.substr(1, endpos - 1);

				val.SetValueType(ObjectValue);

				Value & childval = val[key]; //刚开始得到是一个空的value

				ParseObject(childval, key);
			}
		}
	}
	catch(runtime_error &e)
	{
		return invalid_data;
	}

	return 0;
}

int ConfReader::ParseObject(Value & current, string key)
{
	current.SetValueType(ObjectValue);

	string cont;

	char szmsg[1000] = {0};

	//考虑如何结束本次对象的递归
	while(!input.eof())
	{
		++currentline;
		getline(input, cont);

		if (cont.empty())
		{
			continue;
		}

		int start = 0;
		//跳过前面空格
		while(start < cont.size() && strchr(" \t\n", cont[start]))
		{
			++start;
		}

		//start与end都是下标表示
		int end = cont.size() - 1;
		//跳过后面空格
		while(end > start && strchr(" \t\n", cont[end]))
		{
			--end;
		}

		//就1字节数据，明显不够
		if (end == start)
		{
			//数据异常
			sprintf(szmsg, "valid data's size must larger than 1 byte. line=%d, col=%u", currentline, start);
			errmsg = szmsg;

			throw runtime_error("invalid_data");
		}

		//开始分析当前行的数据
		if ('<' == cont[start] && isalnum(cont[start+1]))
		{
			//new object
			ParseObjectBegin(cont, current, start, end);
		}
		else if ('<' == cont[start] && '/' == cont[start+1])
		{
			ParseObjectEnd(cont, key, start, end);

			//当前对象解析结束
			return 0;
		}
		else if (string::npos != cont.find('='))
		{
			//非对象类型数据
			int pos = cont.find('=');
			int endpos = pos - 1;
			//排除key后面的空格
			while(endpos >= start && strchr(" \t\n", cont[endpos]))
			{
				--endpos;
			}

			string curkey = cont.substr(start, endpos - start + 1);

			//判断值的数据类型
			int value_start = pos + 1;

			while(value_start <= end && strchr(" \t\n", cont[value_start]))
			{
				++value_start;
			}

			string val = cont.substr(value_start, end - value_start + 1);
			Value & childval = current[curkey];

			//判断值类型
			if (IsNumber(val))
			{
				//数字
				childval.SetValueType(IntValue);

				ParseInt(childval, val);
			}
			else if ('(' == val[0] && ')' == val[val.size() - 1])
			{
				//解析数组
				childval.SetValueType(ArrayValue);
				ParseArray(childval, val);
			}
			else
			{
				//解析字符串
				childval.SetValueType(StringValue);
				ParseString(childval, val);
			}
		}
		else
		{
			sprintf(szmsg, "unexpeceted data in line=%d", currentline);
			errmsg = szmsg;

			throw runtime_error("invalid_data");
		}
	}

	return 0;
}

int ConfReader::ParseString(Value & current, string & content)
{
	current.SetStringValue(content);

	return 0;
}

int ConfReader::ParseInt(Value & current, string & content)
{
	int ival = atoi(content.c_str());

	current.SetIntValue(ival);

	return 0;
}

int ConfReader::ParseArray(Value & current, string & content)
{
	//数组
	string strval = content.substr(1, content.size() - 2);

	vector<string>  results;

	//切割字符串
	SplitString(strval, ',' , results);

	for(int i = 0; i < results.size(); ++i)
	{
		Value & childval = current[i];

		string val = results[i];
		TrimString(val);

		//判断值类型
		if (IsNumber(val))
		{
			//数字
			childval.SetValueType(IntValue);
			ParseInt(childval, val);
		}
		else
		{
			//解析字符串
			childval.SetValueType(StringValue);
			ParseString(childval, val);
		}
	}

	return 0;
}

void ConfReader::SplitString(string & str, char delim, vector<string> & results)
{
	results.clear();

	if(str.length() == 0)
	{
		return;
	}

	int  lastPos = 0;
	int  pos = 0;

	while((lastPos = str.find_first_of(delim,pos)) != string::npos)
	{
		results.push_back(str.substr(pos,lastPos - pos));
		pos = lastPos + 1;
	}

	results.push_back(str.substr(pos,str.length() - pos));
}

void ConfReader::TrimString(string & str)
{
	int start = 0;
	//跳过前面空格
	while(start < str.size() && strchr(" \t\n", str[start]))
	{
		++start;
	}

	//start与end都是下标表示
	int end = str.size() - 1;
	//跳过后面空格
	while(end > start && strchr(" \t\n", str[end]))
	{
		--end;
	}

	str = str.substr(start, end - start + 1);
}

bool ConfReader::IsNumber(string & content)
{
	for(int i = 0; i < content.size(); ++i)
	{
		if (!isdigit(content[i]))
		{
			return false;
		}
	}

	return true;
}

int ConfReader::ParseObjectBegin(string & cont, Value & current, int start, int end)
{
	char szmsg[1000] = {0};

	int endpos = cont.find('>');

	if (endpos == string::npos)
	{
		sprintf(szmsg, "expected character > in line=%d, col=%d", currentline, end);
		errmsg = szmsg;

		throw runtime_error("invalid_data");
	}

	int offset = 1;
	string curkey = cont.substr(start + offset, endpos - start - offset);

	Value & childval = current[curkey];

	ParseObject(childval, curkey);

	return 0;
}

int ConfReader::ParseObjectEnd(string & cont, string & expectkey, int start, int end)
{
	char szmsg[1000] = {0};

	//获取字符串的名称
	int endpos = cont.find('>', start);

	if (endpos == string::npos)
	{
		sprintf(szmsg, " expected character > in line=%d, col=%d", currentline, end);
		errmsg = szmsg;

		throw runtime_error("invalid_data");
	}

	int offset = 2;

	//因为要排除结尾处的字符.
	string curkey = cont.substr(start + offset, endpos - start - offset);

	if (expectkey != curkey)
	{
		sprintf(szmsg, "expected key error. in line=%d, col=%d, expected=%s", currentline, endpos, expectkey.c_str());
		errmsg = szmsg;

		throw runtime_error("invalid_data");
	}

	return 0;
}

